<template>
  <div class="search-root-class" :style="[getSearchRootStyle()]">
    <div class="search-main-search" :style="[getMainToolStyle()]">
      <div v-show="config.toolMode === 'main-top'" class="search-table-title search-table-title-main">
        {{ config.title }}
      </div>
      <div class="search-area" :style="[getTopSearchStyle()]">
        <el-form style="display: flex;flex-direction: row;align-items: center;">
          <SearchItemWrap :search="config.search"/>
        </el-form>
        <div style="display: flex;flex-direction: row;align-items: center;height: 100%; margin-right: 16px;">
          <template v-for="(item) in searchAction" :key="item.name">
            <el-button :size="item.size" :type="item.type" :icon="item.icon" @click="() => item.action()">
              {{ item.label }}
            </el-button>
          </template>
          <el-button :size="config.layout.buttonSize" :icon="moreIcon"
                     v-if="showMoreButton" :disabled="disableMoreButton"
                     @click="onMoreSearch">更多...
          </el-button>
        </div>
      </div>
      <!-- 扩展搜索区域 -->
      <div class="search-extra-area" :style="[getTopExtraSearchStyle()]" v-show="showExtra">
        <SearchItemWrap :search="config.extraSearch"/>
      </div>
    </div>
    <slot name="tableTop" />
    <div class="search-main-table-area" :style="[getMainTableAreaStyle()]">
      <TableWidget ref="refTable" :col-type="cfgProps.colType" :hide-table-tool="cfgProps.hideTableTool"
                   :load="loadData" :columns="cfgProps.columns" :pagination="cfgProps.pagination"
                   :hide-pageable="config.hidePageable" :has-select="config.hasSelect">
        <template v-slot:toolHeader>
          <div style="display: flex; align-items: center;">
            <div v-show="config.toolMode === 'table-top'" class="search-table-title">
              {{ config.title }}
            </div>
            <slot name="searchHeader" />
          </div>
        </template>
        <template v-slot:toolBefore>
          <slot name="searchBefore" />
        </template>
        <template v-slot:colExpand="scope">
          <slot name="colExpand" :row="scope.row" />
        </template>
      </TableWidget>
    </div>
  </div>
</template>

<script setup lang="ts">

import {onMounted, ref, shallowRef, toRaw} from "vue";
import SearchItemWrap from "@/components/common/SearchItemWrap.vue";
import TableWidget from "@/widget/TableWidget.vue";

const refTable = ref(null);

const cfgProps = withDefaults(defineProps<{
  loadData?: any,
  colType?: any,
  canPage?: boolean,
  columns: any,
  hideTableTool?: boolean,
  pagination: Pagination,
  config: SearchConfig
}>(), {
  canPage: true,
  columns: [],
  pagination: () => {
    return {
      current: 1,
      pageSize: 10,
      total: 0,
      sizes: [10, 20, 50, 100],
    }
  },
  config: () => {
    return {
      hasSelect: false,
      showSearch: true,
      toolMode: 'main-top',
      defSearchAction: true,
      search: undefined,
      extraSearch: undefined,
      searchAction: undefined,
      tableAction: undefined,
      setting: {
        showMoreSearch: false,
        showMoreButton: true,
        disableMoreButton: true,
        searchBackground: '#fff',
        extraSearchBackground: '#fff',
      },
      layout: {
        buttonSize: 'small',
        actionButtonSize: 'small',
        inputSize: 'small',
      },
    }
  }
});

const config = cfgProps.config;
const pagination = cfgProps.pagination;

const resetDefaults = () => {
  if (config.search) {
    config.search.forEach(item => {
      item.value = item.defValue;
    })
  }

  if (config.extraSearch) {
    config.extraSearch.forEach(item => {
      item.value = item.defValue;
    })
  }
}

const buildPageParams = () => {
  const params: Record<string, any> = {};
  params['current'] = toRaw(pagination.current);
  params['pageSize'] = toRaw(pagination.pageSize);
  return params;
}

const buildSearchParams = (searchData: SearchItem[] | undefined) => {
  const params: Record<string, any> = {};
  if (searchData) {
    searchData.forEach(item => {
      if (item.value) {
        params[item.name] = toRaw(item.value);
      }
    })
  }
  return params;
}

const buildParams = () => {
  return {
    ...buildSearchParams(config.search),
    ...buildSearchParams(config.extraSearch),
    ...buildPageParams(),
  }
}

const loadData = async () => {
  const params = buildParams();
  return await cfgProps.loadData(params);
}

const executeSearch = async () => {
  refTable.value?.refreshData();
}

const refresh = async () => {
  await executeSearch();
}

const searchAction = shallowRef<SearchAction[]>(config.searchAction || [
  {
    type: 'danger',
    name: 'clear',
    label: '清空',
    icon: 'Close',
    size: config.layout.buttonSize,
    action: () => resetDefaults(),
  },
  {
    type: 'primary',
    name: 'clear',
    label: '查询',
    icon: 'Search',
    size: config.layout.buttonSize,
    action: () => executeSearch(),
  }
])

const moreIcon = ref('ArrowDown');
const disableMoreButton = ref(config.setting?.disableMoreButton);
const showExtra = ref(config.setting?.showMoreSearch || false);
const showMoreButton = shallowRef(config.setting.showMoreButton);

const onMoreSearch = () => {
  showExtra.value = !showExtra.value;
}

const getSearchRootStyle = () => {
  return {
    "background": config.setting.rootBackground || "#FFFFFF",
    "margin": config.setting.pageMargin || "0",
  }
}

const getMainTableAreaStyle = () => {
  return {
    "margin": config.setting.tableMargin || "0",
    "padding": config.setting.tablePadding || "0",
  }
}

const getMainToolStyle = () => {
  return {
    "background": config.setting.searchBackground || '#fff',
  }
}

const getTopSearchStyle = () => {
  return {
    "margin": '0 0 4px 0',
    "justifyContent": config.setting.topSearchLayout || 'space-between',
  }
}

const getTopExtraSearchStyle = () => {
  return {
    "background": config.setting.extraSearchBackground || "#fff"
  }
}

onMounted(() => {
  console.log('--- search table onMounted: ');
  resetDefaults();
  executeSearch();
})

defineExpose({
  resetDefaults,
  executeSearch,
  refresh,
})

</script>

<style scoped>
.search-root-class {
  height: 100%;
  width: 100%;
  display: flex;
  flex: 1;
  flex-direction: column;
}

.search-main-search {
  background: #333840;
  width: 100%;
  margin: 0;
  padding: 16px;
  display: flex;
  min-height: 60px;
  flex-direction: column;
  justify-content: stretch;
  align-items: stretch;
  box-shadow: 0 0 0 0 rgba(0, 0, 0, 0.1);
}

.search-area {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
}

.search-main-table-area {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.search-extra-area {
  padding: 16px 0 8px;
  display: flex;
  flex-direction: row;

  border-radius: 4px;
  font-size: 12px;
  margin-top: 16px;
  flex-wrap: wrap;
  width: 100%;
  justify-content:flex-start;
}

.search-table-title {
  color: #222;
  font-size: 16px;
  font-weight: bold;
}

.search-table-title-main {
  margin-bottom: 16px;
}

</style>
